package com.ht.api.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ht.api.db.Db;
import com.ht.api.db.DbConfig;
import com.ht.api.db.DbList;
import com.ht.api.db.Entity;
import com.ht.api.db.bean.Column;
import com.ht.api.db.task.HtTaskExecutor;
import com.ht.api.db.util.SysParamUtil;
import lombok.extern.slf4j.Slf4j;

import javax.sql.DataSource;
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;

@Slf4j
public class CustomerService {

    public static Entity getCustomerArchives (DataSource ds, JSONObject param) {
        String oneid = param.getStr("oneid");
        String unionid = param.getStr("unionid");
        String openid = param.getStr("openid");
        String userid = param.getStr("userid");

        String usersql = "select main_id,oneid,nickname,aliasname,avatar,gender from user_main where status = 0 ";
        if (StrUtil.isNotBlank(oneid)) {
            usersql += "and main_id = " + oneid;
        } else {

            String uid = "";
            if (StrUtil.isNotBlank(unionid)) {
                uid = unionid;
            } else if (StrUtil.isNotBlank(openid)) {
                uid = openid;
            } else if (StrUtil.isNotBlank(userid)) {
                uid = userid;
            }

            usersql += " and bitmap_contains(users, "+Math.abs(uid.hashCode())+")";
        }
        Entity user = Db.findOne(ds, usersql);

        if (user == null) {
            return null;
        }

        List<Runnable> taskList = new ArrayList<>();

        taskList.add(() -> {
            DbList userOriginList = Db.createSqlParser("user_origin").select("distinct openid").where("oneid", user.getStr("oneid")).query(ds);
            user.set("openids", userOriginList.getFieldDataList("openid"));
        });

        taskList.add(() -> {
            JSONObject userProfile = getUserProfileTables();
            getCustomerBaseInfo(ds, user, userProfile);
        });

        taskList.add(() -> {
            getWorkUserList(ds, user);
        });

        taskList.add(() -> {
            getGroupChatList(ds, user);
        });

        HtTaskExecutor.execute(taskList);

        return user;
    }
    
    /**
     * 查询企微客户的类型
     * @param ds
     * @param appid
     * @param externalUserid
     * @return
     */
    public static int getCustomerType(DataSource ds, String appid, String externalUserid) {
    	Integer type = Db.createSqlParser("wx_workuser_customer").select("type")
    		.where("tenant_appid", appid)
    		.where("external_userid", externalUserid)
    		.val(ds, Integer.class);
    	if (type != null) {
    		return type;
    	} else {
    		return 0;
    	}
    }

    /**
     * 获取用户画像数据
     * @param ds
     * @param user
     */
    private static void getCustomerBaseInfo (DataSource ds, Entity user, JSONObject userProfile) {
        List<Runnable> taskList = new ArrayList<>();
        user.set("profiles", JSONUtil.createObj());

        JSONArray profiles = userProfile.getJSONArray("profiles");

        for (int i = 0; i < profiles.size(); i++) {
            JSONObject groupProfile = profiles.getJSONObject(i);
            String groupName = groupProfile.getStr("group_name");
            user.putByPath("profiles." + groupName, JSONUtil.createObj());
            JSONArray tables = groupProfile.getJSONArray("tables");
            for (int k = 0; k < tables.size(); k++) {
                JSONObject table = tables.getJSONObject(k);
                String tableCode = table.getStr("code");
                String tableName = table.getStr("name");
                taskList.add(() -> {
                    Entity entity = Db.createSqlParser(tableCode).selectFilter("main_id,sys_time,sys_deleted,sys_creator,oneid").where("main_id", user.getMainId()).findOne(ds);
                    List<Column> columnList = DbConfig.columnList(tableCode);
                    JSONObject data = JSONUtil.createObj();

                    List<String> filterCodes = Arrays.asList("table","main_id","sys_time","sys_deleted","sys_creator","oneid");
                    for (Column column : columnList) {
                        if (filterCodes.contains(column.getCode())) {
                            continue;
                        }

                        Object value = "";
                        Long daysBetween = null;
                        if (!entity.isNull(column.getCode())) {
                            value = entity.get(column.getCode());

                            if (column.getType().equals("datetime")) {
                                // 计算天数差
                                try {
                                    daysBetween = DateUtil.betweenDay(DateUtil.parse(value.toString()), DateUtil.date(), false);
                                } catch (Exception e) {

                                }
                            }
                        }

                        data.set(column.getName(), value);
                        if (daysBetween != null) {
                            data.set(column.getName().replaceAll("时间", "距今"), daysBetween.intValue() + " 天");
                        }
                    }

                    user.putByPath("profiles." + groupName + "." + tableName, data);
                });
            }

        }

        HtTaskExecutor.execute(taskList);
    }

    /**
     * 获取所有的用户画像表
     * @return
     */
    private static JSONObject getUserProfileTables(){
//        String str = SysParamUtil.getStr("user_profile_tables");
//        if (StrUtil.isNotBlank(str)) {
//            return Arrays.asList(str.split(","));
//        } else {
//            return new ArrayList<>();
//        }

        JSONObject userProfile = JSONUtil.createObj();

        JSONArray profiles = JSONUtil.createArray();
        userProfile.set("profiles", profiles);

        DbList groupList = Db.createSqlParser("sys_group").where("parent_id", "1877906840768090112").query();

        int count = 0;
        for (Entity entity : groupList) {
            JSONObject groupTable = JSONUtil.createObj();
            String groupId = entity.getStr("main_id");
            String groupName = entity.getStr("group_name");

            groupTable.set("group_name", groupName);
            DbList tableList = Db.query("select code,name from db_table where sys_deleted = 1 and group_id = " + groupId);

            groupTable.set("tables", tableList);

            profiles.add(groupTable);
            count += tableList.size();
        }

        userProfile.set("count", count);

        return userProfile;
    }

    private static void getWorkUserList (DataSource ds, Entity user) {
        List<Runnable> taskList = new ArrayList<>();

        DbList list = Db.createSqlParser("user_origin").select("openid external_userid,touch_id userid,status,in_time,exit_time").where("oneid", user.getMainId()).where("touch", 1).query(ds);

        if (list.size() == 0) {
            return;
        }

        int normalCount = 0;
        String firstInTime = null;
        for (Entity entity : list) {
            normalCount += entity.getInt("status") == 1 ? 1 : 0;
            if(firstInTime == null) {
                firstInTime = entity.getStr("in_time");
            }
            taskList.add(() -> {
                String userid = entity.getStr("userid");
                Entity workuser = Db.createSqlParser("wx_workuser").select("gender,name,alias,avatar,userid").where("userid", userid).order("in_time", "asc").findOne(ds);
                entity.set("workuser", workuser);
            });
        }

        HtTaskExecutor.execute(taskList);
//        user.set("workuser_list", list);

        JSONObject workuserInfo = JSONUtil.createObj();
        workuserInfo.set("first_add_time", firstInTime);
        workuserInfo.set("first_add_ago", formatDaysFromToday(firstInTime));
        workuserInfo.set("count", list.size());

        String status = "全部正常";
        if (normalCount == 0) {
            status = "全部删除";
        } else if (normalCount < list.size()) {
            status = "部分正常";
        }
        workuserInfo.set("status", status);

        user.set("workuserInfo", workuserInfo);

    }

    private static void getGroupChatList (DataSource ds, Entity user) {
        List<Runnable> taskList = new ArrayList<>();
        DbList list = Db.createSqlParser("user_origin").select("openid external_userid,touch_id chat_id,status,in_time,exit_time").where("oneid", user.getMainId()).where("touch", 2).order("in_time", "asc").query(ds);

        if (list.size() == 0) {
            return;
        }

        int normalCount = 0;
        String firstInTime = null;
        for (Entity entity : list) {
            normalCount += entity.getInt("status") == 1 ? 1 : 0;

            if(firstInTime == null) {
                firstInTime = entity.getStr("in_time");
            }
            taskList.add(() -> {
                String chatId = entity.getStr("chat_id");
                Entity groupchat = Db.createSqlParser("wx_groupchat").select("name,avatar,chat_id,chat_status").where("chat_id", chatId).findOne(ds);
                entity.set("groupchat", groupchat);
            });
        }
        HtTaskExecutor.execute(taskList);
//        user.set("groupchat_list", list);

        JSONObject groupChatInfo = JSONUtil.createObj();
        groupChatInfo.set("first_in_time", firstInTime);
        groupChatInfo.set("first_in_ago", formatDaysFromToday(firstInTime));
        groupChatInfo.set("count", list.size());

        String status = "全部正常";
        if (normalCount == 0) {
            status = "全部退出";
        } else if (normalCount < list.size()) {
            status = "部分正常";
        }
        groupChatInfo.set("status", status);

        user.set("groupChatInfo", groupChatInfo);
    }

    public static String formatDaysFromToday(String dateString) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        try {
            LocalDate inputDate = LocalDate.parse(dateString, formatter);
            LocalDate today = LocalDate.now();

            Period period = Period.between(inputDate, today);

            int years = period.getYears();
            int months = period.getMonths();
            int days = period.getDays();

            if (years >= 1) {
                return String.format("%d年%d个月前", years, months);
            } else if (months * 30 + days > 90) {
                return String.format("%d个月%d天前", months, days);
            } else {
                int totalDays = (int) inputDate.until(today).getDays();
                return String.format("%d天前", totalDays);
            }
        } catch (DateTimeParseException e) {
            return "日期格式错误，请使用yyyy-MM-dd格式";
        }
    }

    

}
